package com.ruoyi.caipiao.utils;

import cn.hutool.core.date.DateUtil;
import com.sun.org.apache.regexp.internal.RE;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;

import java.io.File;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;

/**
 * @author wangcen
 * @date 2023/12/9 13:59
 */
@Slf4j
public class SsqNumUtil {
    static int coreCount = Runtime.getRuntime().availableProcessors();//核心数
    public static ThreadLocal<LinkedList<Integer>> RED_NUM_LOCAL = new ThreadLocal<>();
    public static ThreadLocal<LinkedList<Integer>> BLUE_NUM_LOCAL = new ThreadLocal<>();
    public static LinkedList<Integer> RED_NUM_INIT = new LinkedList<>();
    public static LinkedList<Integer> BLUE_NUM_INIT = new LinkedList<>();
    public static ThreadPoolExecutor threadPoolExecutor;

    static {
//        initData();
        for (int i = 1; i <= 33; i++) {
            RED_NUM_INIT.add(i);
        }
        for (int i = 1; i <= 16; i++) {
            BLUE_NUM_INIT.add(i);
        }
        threadPoolExecutor = new ThreadPoolExecutor(coreCount - 1,
                coreCount - 1,
                10,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(5000),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.CallerRunsPolicy());
    }

    @Test
    public void test1() {

        int i1 = ThreadLocalRandom.current().nextInt(30000000, 80000000);
        int i2 = ThreadLocalRandom.current().nextInt(30000000, 80000000);
        int i3 = ThreadLocalRandom.current().nextInt(30000000, 80000000);
        int i4 = ThreadLocalRandom.current().nextInt(30000000, 80000000);
        int i5 = ThreadLocalRandom.current().nextInt(30000000, 80000000);


        for (int i = 0; i < 100000000; i++) {
            initData();
            if (i == i1
                    || i == i2
                    || i == i3
                    || i == i4
                    || i == i5
            ) {

                System.out.println(i + ":  " + SsqNumUtil.getNum());
                if (i == i5) {
                    break;
                }
            } else {
                SsqNumUtil.getNum();
            }
        }
    }

    //    @Test
//    public void test2() {
//
//        long st = System.currentTimeMillis();
//
//        getNums(500000);
//
//
//        long ed = System.currentTimeMillis();
//        System.out.println((ed - st));
//
//    }
    @org.junit.Test
    public void test13() {
        String f = "D:\\ssq\\pc20251108.txt";
        String f2 = "D:\\ssq\\pc" + DateUtil.format(new Date(), "yyyyMMdd") + ".txt";
        Set<String> set = MyFileUtil.readFileToSet4(new File(f));
        Set<String> set2 = MyFileUtil.readFileToSet4(new File(f2));
        set.addAll(set2);
        int i = 0;
        int c = 0;
        for (; ; ) {
            String num = getNum();
            if (!set.contains(num)) {
                MyFileUtil.writeContentToFile(f2, (++i) + "预测号码:" + num, true);
                log.info("预测号码:" + num);
                c++;
                if (c == 5) {
                    break;
                }
            }
        }
    }
    @org.junit.Test
    public void test12() throws ExecutionException, InterruptedException {
        String f = "D:\\ssq\\pc" + DateUtil.format(new Date(), "yyyyMMdd") + ".txt";
        Set<String> pcAll = new TreeSet<>();
        for (int i = 0; i < 10000000; i++) {
            Set<String> pc1 = this.caNums();
            pcAll.addAll(pc1);//排除得全部
            MyFileUtil.writeContentToFile(f, i + pc1.toString() + "\n", true);
            log.info("排出总数：" + pcAll.size());
        }
        MyFileUtil.writeContentToFile(f, "排出总数：" + pcAll.size(), true);
        int i = 0;
        int c = 0;
        for (; ; ) {
            String num = getNum();
            if (!pcAll.contains(num)) {
                MyFileUtil.writeContentToFile(f, (++i) + "预测号码:" + num, true);
                log.info("预测号码:" + num);
                c++;
                if (c == 5) {
                    break;
                }
            }
        }
    }

    private Set<String> caNums() throws InterruptedException, ExecutionException {
        CompletableFuture<Set<String>> s1 = CompletableFuture.supplyAsync(() -> getNums(300000), threadPoolExecutor);
        CompletableFuture<Set<String>> s2 = CompletableFuture.supplyAsync(() -> getNums(400000), threadPoolExecutor);
        CompletableFuture<Set<String>> s3 = CompletableFuture.supplyAsync(() -> getNums(500000), threadPoolExecutor);
//        CompletableFuture<Set<String>> s4 = CompletableFuture.supplyAsync(() -> getNums(500000), threadPoolExecutor);
        CompletableFuture<Set<String>> s11 = CompletableFuture.supplyAsync(() -> getNums(300000), threadPoolExecutor);
        CompletableFuture<Set<String>> s22 = CompletableFuture.supplyAsync(() -> getNums(400000), threadPoolExecutor);
        CompletableFuture<Set<String>> s33 = CompletableFuture.supplyAsync(() -> getNums(500000), threadPoolExecutor);
//        CompletableFuture<Set<String>> s44 = CompletableFuture.supplyAsync(() -> getNums(500000), threadPoolExecutor);
        CompletableFuture.allOf(s1, s2, s3).get();
        CompletableFuture.allOf(s11, s22, s33).get();
        Set<String> pc1 = s1.get();
        pc1.retainAll(s2.get());
        pc1.retainAll(s3.get());
//        pc1.retainAll(s4.get());
        Set<String> pc11 = s11.get();
        pc11.retainAll(s22.get());
        pc11.retainAll(s33.get());
//        pc11.retainAll(s44.get());
        pc1.addAll(pc11);
        return pc1;
    }

    public static void initData() {

        LinkedList<Integer> RED_NUM = RED_NUM_LOCAL.get();
        if (RED_NUM == null) {
            RED_NUM_LOCAL.set(new LinkedList<>(RED_NUM_INIT));
        }
        LinkedList<Integer> BLUE_NUM = BLUE_NUM_LOCAL.get();
        if (BLUE_NUM == null) {
            BLUE_NUM_LOCAL.set(new LinkedList<>(BLUE_NUM_INIT));
        }
        RED_NUM = RED_NUM_LOCAL.get();
        BLUE_NUM = BLUE_NUM_LOCAL.get();
        RED_NUM.clear();
        BLUE_NUM.clear();
//        RED_NUM.addAll(RED_NUM_INIT);
//        BLUE_NUM.addAll(BLUE_NUM_INIT);
//        RED_NUM_LOCAL.set(new LinkedList<>(RED_NUM_INIT));
//        BLUE_NUM_LOCAL.set(new LinkedList<>(BLUE_NUM_INIT));
        for (int i = 1; i <= 33; i++) {
            RED_NUM.add(i);
        }
        for (int i = 1; i <= 16; i++) {
            BLUE_NUM.add(i);
        }
    }

    public static Set<String> getNums(int size) {
        Set<String> set = new TreeSet<>();
        for (int i = 0; i < size; i++) {
            set.add(getNum());
        }
        return set;
    }

    public static String getNum() {
        initData();
        List<Integer> nums = new ArrayList<>();
        TreeSet<Integer> sets1 = new TreeSet<>();
        for (int i = 0; i < 6; i++) {
            int n = ThreadLocalRandom.current().nextInt(RED_NUM_LOCAL.get().size());
            sets1.add(RED_NUM_LOCAL.get().get(n));
            RED_NUM_LOCAL.get().remove(n);
        }
        TreeSet<Integer> sets2 = new TreeSet<>();
        for (int i = 0; i < 1; i++) {
            int n = ThreadLocalRandom.current().nextInt(BLUE_NUM_LOCAL.get().size());
            sets2.add(BLUE_NUM_LOCAL.get().get(n));
            BLUE_NUM_LOCAL.get().remove(n);
        }

        nums.addAll(sets1);
        nums.addAll(sets2);
        return nums.toString().replace("[", "").replace("]", "").replaceAll(",", "");
    }

    public static Set<String> getFj(Set<String> set) {
        Set<String> fj = new TreeSet<>();
        for (int i = 1; i <= 33; i++) {
            if (!set.contains(i + "")) {
                fj.add(i + "");
            }
        }
        return fj;
    }

    public static Set<String> getFj2(Set<String> set) {
        Set<String> fj = new TreeSet<>();
        for (int i = 1; i <= 16; i++) {
            if (!set.contains(i + "")) {
                fj.add(i + "");
            }
        }
        return fj;
    }
}
